iT邦幫忙

2024 iThome 鐵人賽

DAY 9
0
Modern Web

Dive into CSS Challenge:從問題到解決方案的實踐之旅系列 第 9

Day 9 - CSS Challenge #6:Profile卡片介面(下)

  • 分享至 

  • xImage
  •  

題目

CSS Challenge Day6
https://ithelp.ithome.com.tw/upload/images/20240919/20169403m3oO3a0wtR.png

上面的圖是題目,而我們要做出幾乎一樣的樣子,題目中還有附上出題官方的CodePen,也有附上給我們解題用的template,當我們真的不會的時候,還是可以參考他們的寫法,所以沒有想像中困難。

我做好的此題CSS Challeage解答

前情提要

上一集由於篇幅太長,拆分兩集來寫。
https://ithelp.ithome.com.tw/upload/images/20240919/201694037g8bgRExZd.png
先讓大家回憶一下我們昨天做到這個樣子,今天要來做題目上最複雜的頭像區塊(主要複雜的是那個動畫)

開始解題

頭像區塊

<div class="profile">
	<div class="profilePic">
		<div class="curve-1"></div>
		<div class="curve-2"></div>
		<img src="...">
	</div>
    ...
</div>

這邊先把 .profilePic 這區的內容先開版出來。
首先,裡面會有兩個分別取名為 .curve-1 .curve-2div 做為頭像外圍的兩個圈圈,晚點我們做動畫的時候要用。
比較外圍的那個圓弧,我稱為 .curve-1,內圈較小圈的是 .curve-2
接著是頭像本人,這樣基礎架構就好了。

如果這邊你想要引用你自己的一些圖片的話,我是用我之前放在 github.io 的圖片,給大家參考。

ProfilePic 區塊

$profilePicWH: 70px;

.profilePic {
	position: relative;
	width: $profilePicWH;
	height: $profilePicWH;
	cursor: pointer;
			
	img {
		width: $profilePicWH;
		height: $profilePicWH;
		border-radius: 100%;
		overflow: hidden;
	}
    ...
}

這邊我先設定最外圈的 .profilePic 的寬高。

再來為了等等的動畫作一些預先設定,先使用 cursor: pointer 修改它的滑鼠指上時的游標為手指,再設定這個區塊為 relative,讓這個區塊是個畫布,等等我們動畫的兩個圓弧圖案才能以它為父項做旋轉。

再來設定頭像本人,這邊我直接寫在 img 上面,設定它的寬高,並用 border-radius: 100% 讓他成為一個圓形。

https://ithelp.ithome.com.tw/upload/images/20240920/20169403m0vbVCSibb.png

頭像外圍圓弧區塊

這種圓弧的製作方式,其實就是一個正常四邊都有 border 的方塊,我們用 border-radius 設定它變成一個圓形,然後把其中一邊的 border 的顏色換成 transparent,這樣看起來就會是一個缺了一邊的圓弧。

這邊我們需要製作兩個同心圓,這兩個圓的視覺上要感覺平均,不會有一圈的白空隙較大或較小,或歪左歪右之類的。
我看很多人在做這段的時候,都是可能不太熟悉 border 的狀態,所以很多人的同心圓間距都歪七扭八的。

https://ithelp.ithome.com.tw/upload/images/20240920/20169403zNyUHYZsSY.png
做起來應該要是這樣漂亮的同心圓。
這段的計算可能很多人不懂,所以所以來講一下我怎麼計算他們的。

$curveSpace: 2px;
$borderWidth: 1px;
$curve1WH: $profilePicWH + ($curveSpace * 4) + ($borderWidth *2);
$curve1Left: ($curveSpace *2)+ ($borderWidth *2);
$curve2WH: $profilePicWH + ($curveSpace * 2);
$curve2Left: $curveSpace + $borderWidth;

基本設定

  • $curveSpace:這代表線條跟線條之間留白的空隙有幾 px
  • $borderWidth:這代表線條的粗細。

然後就要從內側的小圈開始講了:

  • $curve2WH:這是.curve-2 的寬高,我這邊使用了 profilePic 的寬高加上往外擴展的空隙,左右各有兩段空隙,也就是 ($curveSpace * 2)
    但不要忘記,.curve-2 本身是有 border 屬性的,所以他本身的寬度其實是比這樣計算完多加了左右各 1px
  • $curve2Left 這是小圈要往左位移的距離,目前的 (0,0) 是照片的左上角,而我們需要讓他挪移出去。
    這邊的計算方式就是往左位移一個 $curveSpace 的距離,另外要再加上我們本身 border 屬性的 1px

再來講解外側的大圈

  • $curve1WH.curve-1 的寬高,我這邊使用了 profilePic 的寬高,加上兩倍的$curveSpace(因為頭像照片距離最外的大圈,有兩段留白空隙),再加上四倍的 $borderWidth(因為頭像左右各有兩條 border ,其中一條是內圈的,總共4條唷)。
  • $curve1Left:這是大圈要往左位移的距離,因為目前的 (0,0) 是照片的左上角,而我們需要讓他挪移出去。
    這邊的計算方式就是往左位移兩個 $curveSpace 的距離,另外要再加上我們本身 border 屬性的 1px,這邊一樣有兩圈 border,所以是 ($borderWidth *2)

有人可能覺得這邊用 border-box 也可以,但目前這樣的計算方式對我自己來說比較順手,所以就這樣計算了。
目前照我現在的計算方式,不管你怎麼去修改 $curveSpace$borderWidth,你都仍然可以得到計算的很漂亮的同心圓。有興趣的人也可以去我的 CSS Challenge 這邊修改這兩個數值玩看看。

我個人覺得最複雜的地方已經講解完了,接下來就來設定它的樣式。

.profilePic {
    ...
    .curve-1 {
		position: absolute;
		width: $curve1WH;
		height: $curve1WH;
		left: -$curve1Left;
		top: -$curve1Left;
		border-width: $borderWidth;
		border-style: solid;
		border-color: $coffee transparent $coffee $coffee;
		z-index: 2;
		border-radius: 100%;
		transition: all 1.5s ease-in-out;
	}
			
	.curve-2 {
		@extend .curve-1;
		width: $curve2WH;
		height: $curve2WH;
		left: -$curve2Left;
		top: -$curve2Left;
		border-color: $coffee $coffee $coffee transparent;
	}
}

這邊就是將 .curve-1 的樣式完成。
利用 absolute 讓他浮動,利用剛剛的變數將他的位置擺放好,設定好 border 的樣式,依據「上,右,下,左」的順序來設定完4個方向的 border-color,並且加上漸變的重點 transition: all 1.5s ease-in-out

接著我們讓 .curve-2@extend .curve-1 他就會以 .curve-1 為基準,然後我們在他上面做些修改,把剛剛算好的變數位置放進去,也把 border 四邊的顏色改好。圓弧們的基礎樣式就做好了。
https://ithelp.ithome.com.tw/upload/images/20240920/20169403J7z3z03inu.png

接著就是最簡單的部分,我們加上滑鼠指上的漸變。

.profilePic {
    ...
    .curve-1 {...}
    .curve-2 {...}
    &:hover {
        .curve-1 {transform: rotate(360deg)}
		.curve-2 {transform: rotate(-360deg)}
    }
}

這樣,滑鼠指上 profilePic 的時候,他們倆就會朝相反的方向作 rotate ,同時也因為 transition 的效果,在滑鼠離開的時候又會動態回去。
這樣,這一題就做完了。


Wrap up and go home

希望改變了這種按照步驟的寫法,能讓更多人看得懂,也能跟我一樣喜歡上寫CSS。

那今天就先到這裡,明天我們再繼續來玩下一題。


上一篇
Day 8 - CSS Challenge #6:Profile卡片介面(上)
下一篇
Day 10 - CSS Challenge #7:Notification、Menu、Search(上)
系列文
Dive into CSS Challenge:從問題到解決方案的實踐之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言